package cn.com.headfree.service.impl;

import static org.quartz.JobBuilder.newJob;
import static org.quartz.TriggerBuilder.newTrigger;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.Trigger;
import org.quartz.TriggerKey;
import org.quartz.impl.matchers.GroupMatcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import com.gta.edu.sdk.base.service.impl.BaseServiceImpl;

import cn.com.headfree.base.common.ScheduleStatus;
import cn.com.headfree.entity.TCommonTask;
import cn.com.headfree.service.IScheduleService;

@Service("scheduleService")
public class ScheduleServiceImpl extends BaseServiceImpl<TCommonTask> implements IScheduleService {
	private static final Logger log = LoggerFactory.getLogger(ScheduleServiceImpl.class);
	private static final String JOB_CLASS = "cn.com.headfree.job.CommonJob";
	private static final String TASK_GROUP = "common";
	@Autowired
	private RestTemplate template;
	@Autowired
	private Scheduler scheduler;

	@Override
	public void proceedSchedule() {
		try {
			this.proceed();
		} catch (Exception ex) {
			log.error("错误：", ex);
		}
	}

	/**
	 * @description 查询数据库获取所有的待办任务，进行任务执行
	 * @author fengya
	 * @date 2020年7月14日 上午11:17:08
	 * @throws Exception
	 * void
	 */
	private void proceed() throws Exception {
		List<TCommonTask> list = this.findAll(TCommonTask.class, true, null, true);
		if (null == list || list.isEmpty()) {
			return;
		}
		Set<String> currentScheduleCodeSet = this.getCurrentScheduleCodeSet();
		this.proceed(list, currentScheduleCodeSet);
	}

	/**
	 * @description 获取当前所有执行的定时任务编码的集合
	 * @author fengya
	 * @date 2020年7月14日 上午11:19:30
	 * @return
	 * @throws Exception
	 * Set<String>
	 */
	private Set<String> getCurrentScheduleCodeSet() throws Exception {
		Set<JobKey> jobKeySet = scheduler.getJobKeys(GroupMatcher.jobGroupEquals(TASK_GROUP));
		Set<String> scheduleCodeSet = new HashSet<String>();
		for (JobKey jobKey : jobKeySet) {
			scheduleCodeSet.add(jobKey.getName());
		}
		return scheduleCodeSet;
	}

	/**
	 * @description 根据当前的数据库任务列表进行控制定时任务的执行和停止
	 * @author fengya
	 * @date 2020年7月14日 上午11:20:26
	 * @param list
	 * @param currentScheduleCodeSet
	 * @throws Exception
	 * void
	 */
	private void proceed(List<TCommonTask> list, Set<String> currentScheduleCodeSet) throws Exception {
		for (TCommonTask task : list) {
			if (ScheduleStatus.START.ordinal() == task.getStatus()) {// 启用任务
				if (!currentScheduleCodeSet.contains(task.getCode())) {// 未在进程中
					this.startTask(task);
				}

			} else if (ScheduleStatus.STOP.ordinal() == task.getStatus()) {// 停用任务
				if (currentScheduleCodeSet.contains(task.getCode())) {// 已在进程中
					this.stopTask(task);
				}
			}
		}
	}

	public void startTask(TCommonTask scheduleTask) throws Exception {
		Class<? extends Job> clazz = this.getJobClass(JOB_CLASS);
		JobDetail jobDetail = this.getJobDetail(clazz, scheduleTask.getCode(), scheduleTask.getProceedMethod());
		Trigger trigger = this.getTrigger(scheduleTask.getCode(), scheduleTask.getConf());
		this.scheduler.scheduleJob(jobDetail, trigger);
	}

	public void stopTask(TCommonTask scheduleTask) throws Exception {
		this.scheduler.unscheduleJob(TriggerKey.triggerKey(scheduleTask.getCode(), TASK_GROUP));
		this.scheduler.deleteJob(JobKey.jobKey(scheduleTask.getCode(), TASK_GROUP));
	}

	/**
	 * @description 根据参数构造任务
	 * @author fengya
	 * @date 2020年7月15日 上午10:34:47
	 * @param clazz
	 * @param jobName
	 * @param proceedMethod
	 * @return
	 * JobDetail
	 */
	private JobDetail getJobDetail(Class<? extends Job> clazz, String jobName, String proceedMethod) {
		JobBuilder builder = newJob(clazz).withIdentity(jobName, TASK_GROUP);
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("jobCode", jobName);
		params.put("proceedMethod", proceedMethod);
		params.put("template", this.template);
		JobDataMap data = new JobDataMap(params);
		builder.setJobData(data);
		JobDetail jobDetail = builder.build();
		return jobDetail;
	}

	/**
	 * @description 根据类名称构造出类
	 * @author fengya
	 * @date 2020年7月15日 上午10:36:37
	 * @param className
	 * @return
	 * @throws ClassNotFoundException
	 * Class<? extends Job>
	 */
	@SuppressWarnings("unchecked")
	private Class<? extends Job> getJobClass(String className) throws ClassNotFoundException {
		return (Class<? extends Job>) Class.forName(className);
	}

	/**
	 * @description 构造出任务的触发器
	 * @author fengya
	 * @date 2020年7月15日 上午10:37:48
	 * @param triggerName
	 * @param conf
	 * @return
	 * Trigger
	 */
	private Trigger getTrigger(String triggerName, String conf) {
		CronTrigger trigger = newTrigger().withIdentity(triggerName, TASK_GROUP).withSchedule(CronScheduleBuilder.cronSchedule(conf)).startNow().build();
		return trigger;
	}

//	class ScheduleNaming {
//		private String taskCode = "taskCode";
//		private String className;
//		private String triggerName;
//		private String jobName;
//		private String scheduleConfiguration;
//
//		ScheduleNaming(TCommonTask schedule) {
//			if (null != schedule.getCode()) {
//				this.taskCode = schedule.getCode();
//			}
//			this.className = JOB_CLASS;
//			this.triggerName = this.taskCode;
//			this.jobName = this.taskCode;
//			this.scheduleConfiguration = schedule.getConf();
//		}
//
//		public String getClassName() {
//			return className;
//		}
//
//		public String getTriggerName() {
//			return triggerName;
//		}
//
//		public String getJobName() {
//			return jobName;
//		}
//
//		public String getScheduleConfiguration() {
//			return scheduleConfiguration;
//		}
//	}

}
